iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 22
0
Modern Web

實作小範例入門 Vue & Vuex 2.0系列 第 22

vue & vuex 22 - Open Data - II (高雄市 opendata、加上過場 loading 效果)

  • 分享至 

  • xImage
  •  

vue & vuex 22 - Open Data kcg open1999

open 1999

高雄市政府資料開放系統提供派工通報資料。

一次可以 get 600 筆資料,

資料內容滿豐富的,從停水停電到空氣污染等..,

主要是看到高雄防災通,覺得滿好玩的,所以拿這個 API 來練習囉。

資料來源:

今天目標:

  1. 使用高雄市 Open Data: open1999 與資料呈現。
  2. 取得資料的時候,加上過場 loading 動畫。

page/open1999.vue

<template>
  <div class="container">
    <nav class="navbar navbar-default">
      <!-- 略.. -->
    </nav>
    
    <hr>
    
    <!-- 
		card 
		layout 的部分是參考囉.. 可以自己調整。
	-->
    <div class="row">
      <div class="col-md-4 col-sm-6" v-for="item in opendate">
        <div class="thumbnail">
          <span class="label label-warning">{{ item.ZipName_ }}</span>
          <span class="label label-ligth-pink">{{ item.InformDesc_ }}</span>
          <span class="label label-info">{{ item.UnitName_ }}</span>
          <div class="caption">
            <h3>
              <a :href="getGoogleMap( item.address_ )" target="_blank">{{ item.address_ }}</a>
            </h3>
            <p>{{ item.BeforeDesc_ }}</p>
            <small class="text-muted">反應日期:{{ item.Cre_Date_ }}</small>
          </div>
        </div>
      </div>
    </div>

  </div>
</template>

<script>
import { mapGetters, mapActions } from 'vuex';

export default {
  created () {
    // created Hook 發出 action call API
    this.$store.dispatch('open1999');
  },
  computed: mapGetters({
    opendate: 'getOpen1999'
  }),
  methods: {
    ...mapActions([
    ]),
    getGoogleMap(address) {
      return `https://www.google.com/maps/place/${address}`;
    },
  },
};
</script>

address

作為每一筆資料呈現的 title 加上 google map link

整理到一個 method 串好 url 在 bind 到 href

使用 ES6 Template literals

// ES6 Template literals
const str = `https://www.google.com/maps/place/${address}`;
${裡面可以放變數}

// ES5: 
var str = "https://www.google.com/maps/place/" + address;

有了這個就不需要 + + + + + + + T_T" 太感動惹..


store/module/opendata.js

// root types
import * as rootypes from '../mutations_types.js';

const types = {
  OPEN_1999: 'open/OPEN_1999',
}

const state = {
  opendata: [],
}

const getters = {
  getOpen1999: state => state.opendata,
}

const actions = {
  open1999 ({ commit }) {
    // 啟動 loading
    commit(rootypes.LOADING, true);
    
    // use fetch call open 1999 API
    fetch('http://work1999.kcg.gov.tw/open1999/ServiceRequestsQuery.asmx/ServiceRequestsQuery')
      .then(function(response) {
        // fetch 有 'ok' 物件可以判斷 response state 是不是 200
        // 將資料處理成 JSON
        if(response.ok) {
          return response.json();
        } 
        else {
          console.error(response);
          commit(rootypes.LOADING, false);
        }
      })
      .then(function(data) {
        // 把 json 傳給 mutation
        commit(types.OPEN_1999, data);
        // 關閉 loading
        commit(rootypes.LOADING, false);
      })
      .catch(function(error) {
        console.error(error);
        commit(rootypes.LOADING, false);
      });
  },
}

const mutations = {
  [types.OPEN_1999] (state, data) {
    state.opendata = data;
  },
}

export default {
  state,
  getters,
  actions,
  mutations
}

loading 過場動畫

這隻 API 內容滿多的,因此 get 時間大概有 2 ~ 3s 如果沒有任何訊息,

會有系統壞掉的感覺,所以加上滿版過場動畫。

loading 特效,實作方法有很多,可以放 gif 圖片,或者自已刻 css 加上動畫,等方法..

這邊我們使用的是 css-loader 標榜 only one div and pure CSS 就可以做到。

Demo 頁面還有各種範例給你看,超級酷的!

什麼時候加入

我們用簡單的方法,在 root state 儲存一個狀態,loading: false

放在哪?

我們思考這樣的功能未來可能不止這個頁面需要使用,我們不會希望需要用的頁面自己載入這個元件,因此會這是一個全域的特效,任何頁面需要 loading 只要去改變 state 就好!輕鬆方便,因此應該會放在 app.vue 在這裡我們只存放,最上方 navbar 有所有 page 的 link 以及 router 切換後顯示的地方:<router-view></router-view> 因此放在這邊最適合不過了!

app.vue

<template>
<div>
  <!-- loading 拉到最外層,可以讓所有頁面使用。 -->
  <div v-if="loading" class="loader loader-curtain is-active"></div>
  <nav>略...</nav>
  <router-view></router-view>
</div>
<template>

<script>
import { mapGetters } from 'vuex';
export default {
  computed: mapGetters({
    // 取得 loading state
    loading: 'getLoading'
  }),
}
</script>

<style>
  /*
    css-loader
    from: http://www.raphaelfabeni.com.br/css-loader/
  */
  .loader{ loader css.. 略..}
<style>

store/root.js

import * as types from './mutations_types.js';

export const state = {
  loading: false,
}

export const actions = {
  toggleLoading ({ commit }, isLoading) {
    commit(types.LOADING, isLoading);
  },
}

export const mutations = {
  [types.LOADING] (state, isLoading) {
    state.loading = isLoading;
  },
}


github 完整範例:

實作小範例入門 Vue & Vuex 2.0 - github 完整範例

使用 git checkout 切換每天範例。


上一篇
vue & vuex 21 - Open Data - I (元件的生命週期、透過 ajax 取得資料)
下一篇
vue & vuex 23 - Open Data - III (搜尋條件、select option、v-else、watch)
系列文
實作小範例入門 Vue & Vuex 2.030
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言